using System;
using System.Collections.Generic;

using log4net;

using GymManager.Exception;
using GymManager.Mechanism;
using GymManager.Persistence.DAO;
using GymManager.Persistence.VO;

namespace GymManager.Business
{
    /// <summary>
    /// Class responsible by providing services regarding students
    /// </summary>
    public class StudentServices
    {
        // logger instance
        private ILog _logManager = LogManager.GetLogger(typeof(StudentServices));

        /// <summary>
        /// Method responsible by getting information about student in according to a given name
        /// </summary>
        /// <param name="String">student's name</param>
        /// <returns>User - user value object matching with given name</returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public Student findByName(String name)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            Student studentResult = null;

            try
            {
                // getting information about student
                StudentDAO studentDAO = new StudentDAO();
                studentResult = studentDAO.findByName(name);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }            
            
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return studentResult;
        }

        /// <summary>
        /// Method responsible by finding students using any of its properties
        /// </summary>
        /// <param name="Student">student vo</param>
        /// <returns>IList - list of students retrieved in according to filter</returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public IList<Student> findByAny(Student studentVOFilter)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            IList<Student> studentList = null;

            try
            {
                // formating information of student VO filter
                if (!String.IsNullOrEmpty(studentVOFilter.Name))
                {
                    studentVOFilter.Name = "%" + studentVOFilter.Name + "%";
                }

                // getting information about students
                StudentDAO studentDAO = new StudentDAO();
                studentList = studentDAO.findByAny(studentVOFilter);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return studentList;
        }

        /// <summary>
        /// Method responsible by finding all active students
        /// </summary>
        /// <returns>IList - list of students retrieved in according to filter</returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public IList<Student> findAllActive()
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            IList<Student> studentList = null;

            try
            {
                // getting information about students
                StudentDAO studentDAO = new StudentDAO();
                studentList = studentDAO.findAllActive();
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return studentList;
        }

        /// <summary>
        /// Method responsible by adding a new student to database
        /// </summary>
        /// <param name="Student">student information to be saved</param>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public void create(Student studentVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                // adding student to database
                StudentDAO studentDAO = new StudentDAO();
                studentDAO.create(studentVO);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by updating a student information in database
        /// </summary>
        /// <param name="Student">student information to be saved</param>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public void update(Student studentVO)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            try
            {
                // update student into database
                StudentDAO studentDAO = new StudentDAO();
                studentDAO.update(studentVO);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }
        }

        /// <summary>
        /// Method responsible by checking if the student can be cancelled.
        /// In order to a student being cancelled there can't exist any pending 
        /// monthly fees or stock item purchasings.
        /// </summary>
        /// <param name="Int32">student identifier</param>
        /// <returns>Boolean - flag indicating if the student can be cancelled or not </returns>
        /// <see cref="GymManager.Exception.BusinessException"/>
        public Boolean isStudentCanBeCancelled(Int32 studentId)
        {
            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("Begin Method");
            }

            // flag indicating if the student can be cancelled or not
            Boolean isStudentCanBeCancelled = true;

            try
            {
                // check if there are any pendings monthly fee
                MonthlyFeeDAO monthlyFeeDAO = new MonthlyFeeDAO();
                IList<MonthlyFee> monthlyFeeList = monthlyFeeDAO.findPendingsByStudent(studentId);

                // check if there are any pendings sales
                StockItemSalesDAO stockItemSalesDAO = new StockItemSalesDAO();
                IList<StockItemSales> stockItemSalesList = stockItemSalesDAO.findPendingsByStudent(studentId);

                // checking the answers
                isStudentCanBeCancelled = (monthlyFeeList == null || monthlyFeeList.Count == 0) && (stockItemSalesList == null || stockItemSalesList.Count == 0);
            }
            catch (PersistenceException)
            {
                throw new BusinessException();
            }

            if (_logManager.IsInfoEnabled)
            {
                _logManager.Info("End Method");
            }

            return isStudentCanBeCancelled;
        }
    }
}
